<!--  -->
<template>
  <el-dialog title="编辑防火墙规则" v-model="visible" width="450px" :close-on-click-modal="false" @close="handleClose">
    <el-form :model="form" :rules="rules" ref="form" label-width="60px">
      <el-form-item label="名称" prop="description">
        <el-input v-model="form.description"></el-input>
      </el-form-item>
      <el-form-item label="协议族" prop="family">
        <el-select v-model="form.family" placeholder="请选择协议族" style="width: 100%;">
          <el-option v-for="family in enums.family" :key="family.value" :label="family.text" :value="family.value"></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="来源" prop="source">
        <el-input v-model="form.source.address"></el-input>
        <span class="readme">支持当个IP：192.168.0.11或者范围192.168.0.1/24</span>
      </el-form-item>

      <el-form-item label="端口" prop="port">
        <el-input v-model="form.port.port" style="width: 70%;"></el-input>
        <el-select v-model="form.port.protocol" placeholder="请选择协议" style="width: 30%;">
          <el-option v-for="protocol in enums.protocol" :key="protocol.value" :label="protocol.text" :value="protocol.value"></el-option>
        </el-select>
        <span class="readme">单个端口：3306，端口访问：3306-3309，协议默认TCP</span>
      </el-form-item>


      <el-form-item label="服务" prop="service">
        <el-select v-model="form.service.name" filterable clearable placeholder="请选择服务" style="width: 100%;">
          <el-option v-for="service in services" :key="service" :label="service" :value="service"></el-option>
        </el-select>
        <span class="readme">选择服务器中已有的服务</span>
      </el-form-item>

      <el-form-item label="动作" prop="action">
        <el-radio-group v-model="form.action">
          <el-radio v-for="action in enums.action" :key="action.value" :label="action.value">{{action.text}}</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button size="small" @click="visible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="handleConfirm" >确 定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script>
import enums from './enums';
import FirewallApi from '@/api/firewall.api';

export default {
  data () {
    let self = this;
    return {
      enums,
      visible: false,
      services: [],
      form: {},
      src: null,
      rules: {
        source: {trigger: 'blur', validator: (rule, source, callback)=>{
          let value = source.address;
          if(value){
            let form = self.form;
            if(!form.family){
              callback(new Error('请先选择协议族'));
              return;
            }
            // 验证IP
            let ipv4Rex = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}(\/[1-2]\d?)?$/;
            let ipv6Rex = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/;
            if(form.family == 'ipv4'){
              if(!ipv4Rex.test(value)){
                callback(new Error('IPV4格式不正确'));
                return;
              }
            } else if(form.family == 'ipv6'){
              if(!ipv6Rex.test(value)){
                callback(new Error('IPV4格式不正确'));
                return;
              }
            }
          }
          callback();
        }},
        port: {trigger: 'blur', validator: (rule, port, callback)=>{
          let value = port.value;
          if(value){
            let rex = /^\d+(-\d+)?$/;
            if(!rex.test(value)){
              callback(new Error('端口输入错误'));
            }
          }
          callback();
        }},
      }
    };
  },
  emits: ['confirm', 'close'],
  methods: {
    show(data, hostId){
      let self = this;
      self.hostId = hostId;
      self.visible = true;
      self.src = data;
      if(data){
        self.mode = 'edit';
      }else{
        self.mode = 'add';
        data = {};
      }

      let form = {
        action: data.action || 'accept',
        // type: data.type || 'rule',
        port: {},
        source: {},
        service: {}
      };

      if(data.type == 'rule'){
        form.family = data.family || 'ipv4';
        form.port = data.port || {};
        form.source = data.source || {};
        form.service = data.service || {};

      } else if(data.type == 'port'){
        form.port = {
          port: data.port,
          protocol: data.protocol
        };
      } else if(data.type == 'source'){
        form.source = {address: data.address};
      } else if(data.type == 'service'){
        form.service = {name: data.name};
      }


      self.form = form;

      self.initService();
    },
    initService(){
      let self = this;
      FirewallApi.getServiceList(self.hostId).then(res => {
        self.services = res;
      });
    },
    handleClose () {
      this.$emit('close');
    },
    handleConfirm(){
      let self = this;
      self.$refs.form.validate(valid=>{
        if(!valid){
          self.$warn('请检查输入内容');
          return;
        }
        let form = self.form;

        let ruleCount = 0;
        if(form.source.address){
          ruleCount++;
        }
        if(form.port.port){
          form.port.protocol = form.port.protocol || 'tcp';
          ruleCount++;
        }
        if(form.service.name){
          ruleCount++;
        }

        if(ruleCount == 0){
          self.$warn('来源，端口，服务至少选择填写一项');
          return; 
        }

        form.family = form.family || 'ipv4';
        form.action = form.action || 'accept';

        let data;
        
        if(ruleCount > 1 || form.description || form.family != 'ipv4' || form.action=='drop'){
          data = {...form};
          data.type = 'rule';
        } else if(form.source.address){
          data = {...form.source};
          data.type = 'source';

        } else if(form.port.port){
          data = {...form.port};
          data.type = 'port';
        } else if(form.service.name){
          data = {...form.service};
          data.type = 'service';
        }

        self.visible = false;
        self.$emit('confirm', self.mode, data, self.src);

      });
    }
  }
};
</script>

<style scoped>
.readme{
  font-size: 12px;
  color: #adadad;
}
</style>
